/*
 *	Yalala
 *	
 *	Copyright © MediaMonks B.V.
 *	All rights reserved.
 *	
 *	Redistribution and use in source and binary forms, with or without
 *	modification, are permitted provided that the following conditions are met:
 *	1. Redistributions of source code must retain the above copyright
 *	   notice, this list of conditions and the following disclaimer.
 *	2. Redistributions in binary form must reproduce the above copyright
 *	   notice, this list of conditions and the following disclaimer in the
 *	   documentation and/or other materials provided with the distribution.
 *	3. All advertising materials mentioning features or use of this software
 *	   must display the following acknowledgement:
 *	   This product includes software developed by MediaMonks B.V.
 *	4. Neither the name of MediaMonks B.V. nor the
 *	   names of its contributors may be used to endorse or promote products
 *	   derived from this software without specific prior written permission.
 *	
 *	THIS SOFTWARE IS PROVIDED BY MEDIAMONKS B.V. ''AS IS'' AND ANY
 *	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *	DISCLAIMED. IN NO EVENT SHALL MEDIAMONKS B.V. BE LIABLE FOR ANY
 *	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *	
 */

package com.mediamonks.yalala.ui.table 
{
	import nl.acidcats.yalog.common.MessageData;
	import flash.events.Event;
	import temple.ui.scroll.ScrollPane;

	import flash.geom.Rectangle;

	/**
	 * @author Thijs Broerse
	 */
	public class Table extends ScrollPane 
	{
		private static const _ROW_HEIGHT:Number = 14;

		private var _data:Vector.<MessageData>;
		private var _rows:Vector.<Row>;
		private var _rowDataOffset:uint;
		private var _highLight:String;
		private var _contentWidth:Number;

		public function Table() 
		{
			this._data = new Vector.<MessageData>();
			this._rows = new Vector.<Row>();
		}
		
		public function get data():Vector.<MessageData>
		{
			return this._data;
		}
		
		public function set data(data:Vector.<MessageData>):void
		{
			this._data = data;
			
			var len:uint = Math.ceil(this.height / _ROW_HEIGHT);
			len = Math.min(len, this._data.length - this._rowDataOffset);
			len = Math.max(len, this._rows.length);
			
			for (var i:int = 0; i < len; i++)
			{
				if (i >= this._rows.length)
				{
					this.createRow();
				}
				if (i + this._rowDataOffset < this._data.length)
				{
					this._rows[i].data = this._data[i + this._rowDataOffset];
					this._rows[i].highLight(this._highLight);
				}
				else
				{
					this._rows[i].data = null;
				}
			}
			this.dispatchEvent(new Event(Event.RESIZE));
		}

		public function clear():void 
		{
			this._data.length = 0;
			this._rowDataOffset = 0;
			this.scrollV = this.scrollH = 0;
			for each (var row : Row in this._rows)
			{
				row.data = null;
			}
			this.dispatchEvent(new Event(Event.RESIZE));
		}

		public function highLight(text:String):void 
		{
			this._highLight = text;
			
			for each (var row : Row in this._rows) 
			{
				row.highLight(this._highLight);
			}
		}

		override public function get contentWidth():Number 
		{
			if (isNaN(this._contentWidth)) this._contentWidth = 0; 
			
			if (super.contentWidth > this._contentWidth)
			{
				this._contentWidth = super.contentWidth;
			}
			return this._contentWidth;
		}

		override public function get contentHeight():Number 
		{
			return this._data.length * _ROW_HEIGHT;
		}

		override public function set scrollRect(value:Rectangle):void 
		{
			super.scrollRect = value;
			
			if (!this._rows || !this._rows.length || !value) return;
			
			var numRows:uint = this.height / _ROW_HEIGHT + 1;
			
			var i:uint;
			
			// check if we have enough rows
			while (this._data.length > this._rows.length && this._rows.length < numRows)
			{
				this.createRow();
				i = this._rows.length - 1;
				if (i + this._rowDataOffset < this._data.length)
				{
					this._rows[i].data = this._data[i + this._rowDataOffset];
					this._rows[i].highLight(this._highLight);
				}
				else
				{
					this._rows[i].data = null;
				}
			}
			
			// scroll down, move all rows above the top to the buttom of the list
			var row:Row = this._rows[0];
			while (row.y < (value.y - _ROW_HEIGHT))// && (this._rowDataOffset <= (this._data.length - this._rows.length)))
			{
				row.y += this._rows.length * _ROW_HEIGHT;
				
				if (this._rowDataOffset + this._rows.length < this._data.length)
				{
					row.data = this._data[this._rowDataOffset + this._rows.length];
					row.highLight(this._highLight);
				}
				else
				{
					row.data = null;
				}
				this._rows.push(this._rows.shift());
				row = this._rows[0];
				this._rowDataOffset++;
			}
			// scroll up, move rows at the bottom to the top (if needed)
			while (row.y > value.y)
			{
				row = this._rows.pop();
				this._rows.unshift(row);
				row.y -= this._rows.length * _ROW_HEIGHT;
				if (this._rowDataOffset)
				{
					row.data = this._data[--this._rowDataOffset];
					row.highLight(this._highLight);
				}
				else
				{
					row.data = null;
				}
			}
		}

		private function createRow():void 
		{
			var row:Row = new Row();
			
			if (this._rows.length)
			{
				row.y = this._rows[this._rows.length - 1].y + _ROW_HEIGHT;
			}
			this.addChild(row);
			this._rows.push(row);
		}
	}
}
